<template>
  <div>
    <div
      ref="map"
      style="
        position: absolute;
        width: 100%;
        min-width: 500px;
        min-height: 400px;
        height: 100vh;
        text-align: left;
      "
    >
      <pre id="info" />
    </div>
  </div>
</template>

<script>
import { Map, View, Feature } from "ol";
const TileLayer = ol.layer.Tile;
const VectorLayer = ol.layer.Vector;
const { OSM, Vector: VectorSource } = ol.source;
const { Point, LineString, Polygon } = ol.geom;
const { Circle } = ol.geom;
const {
  Fill,
  Icon,
  Stroke,
  Style,
  Text: TextStyle,
  Circle: CircleStyle,
} = ol.style;
const { fromLonLat } = ol.proj;
import positionImage from "@/assets/地点.png";
import walkingImage from "@/assets/步行.png";
import taxiImage from "@/assets/驾车.png";
import subwayImage from "@/assets/公交.png";
import busImage from "@/assets/公交车.png";
import ridingImage from "@/assets/骑行.png";
import arrowImage from "@/assets/箭头.png";
import { PointSelect } from "@/utils/olInteraction";
import projzh from "@/utils/reproject";
const context = {
  map: null,
  traceLayer: [],
  pickerLayer: null,
  interaction: null,
};

export default {
  data() {
    return {};
  },
  props: {
    trace: Array,
  },
  watch: {
    trace: function () {
      context.traceLayer.forEach((l) => {
        context.map.removeLayer(l);
        l.getSource().clear();
        l.addFeatures(this.createOneTrace());
      });
      this.trace.forEach((v, i) => {
        let t = v["trace"] || v["轨迹地图"] || v["轨迹详情"] || v["轨迹"];
        if (t) {
          l = this.createTraceLayer();
          l.addFeatures(
            this.createOneTrace(
              "" + v.uuid,
              t.map((s) => s.trace)
            )
          );
        }
      });
    },
  },
  methods: {
    init() {
      // projzh
      console.log(this.trace)
      const gcj02Extent = [
        -20037508.342789244, -20037508.342789244, 20037508.342789244,
        20037508.342789244,
      ];
      const gcjMecator = new ol.proj.Projection({
        code: "GCJ-02",
        extent: gcj02Extent,
        units: "m",
      });
      ol.proj.addProjection(gcjMecator);
      ol.proj.addCoordinateTransforms(
        "EPSG:4326",
        gcjMecator,
        projzh.ll2gmerc,
        projzh.gmerc2ll
      );
      ol.proj.addCoordinateTransforms(
        "EPSG:3857",
        gcjMecator,
        projzh.smerc2gmerc,
        projzh.gmerc2smerc
      );
      context.map = new Map({
        target: this.$refs.map,
        layers: [
          // new TileLayer({
          //   source: new OSM(),
          // }),
          new ol.layer.Tile({
            source: new ol.source.XYZ({
              projection: gcjMecator,
              url: "http://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=123567&x={x}&y={y}&z={z}",
            }),
          }),
        ],
        view: new View({
          center: fromLonLat([114.3, 30.5]),
          zoom: 10,
        }),
      });
      context.traceLayer.forEach((l) => {
        context.map.removeLayer(l);
        l.getSource().clear();
        l.addFeatures(this.createOneTrace());
      });
      this.trace.forEach((v, i) => {
        let t = v["trace"] || v["轨迹地图"] || v["轨迹详情"] || v["轨迹"];
        if (t) {
          let l = this.createTraceLayer();
          l.addFeatures(
            this.createOneTrace(
              "" + v.uuid,
              t.map((s) => s.trace)
            )
          );
          context.map.addLayer(l);
        }
      });
      if (this.trace && this.trace.length > 0) {
        context.traceLayer
          .getSource()
          .addFeatures(this.createOneTrace("", this.trace));
      }
      context.map.on("pointermove", showInfo);

      var info = document.getElementById("info");
      function showInfo(event) {
        var features = context.map.getFeaturesAtPixel(event.pixel);
        if (features.length == 0) {
          info.innerText = "";
          info.style.opacity = 0;
          return;
        }
        var properties = features[0].getProperties();
        if (properties.type == "icon") {
          info.innerText =
            "\n" +
            "到达时间: " +
            properties.date +
            "\n" +
            "离开时间: " +
            properties.end +
            "\n" +
            "交通工具: " +
            properties.trans_type +
            "\n" +
            "身体状态: " +
            properties.body_state;
          info.style.opacity = 1;
          info.style.left = event.pixel[0] + "px";
          info.style.top = event.pixel[1] - 15 + "px";
        }
      }
      const pickerPoint = new ol.geom.Point(fromLonLat([0, 0]));
      context.interaction = new PointSelect(pickerPoint);
      context.pickerLayer = new ol.layer.Vector({
        source: new ol.source.Vector({
          features: [new ol.Feature(pickerPoint)],
        }),
        visible: false,
        style: new ol.style.Style({
          image: new ol.style.Icon({
            anchor: [0.5, 0.5],
            anchorXUnits: "fraction",
            anchorYUnits: "fraction",
            opacity: 0.95,
            scale: 0.6,
            src: require("@/assets/poi.png"),
          }),
        }),
      });
      context.map.addLayer(context.pickerLayer);
    },
    createPolyon(f, o, r, pos = "u") {
      let p = f.getGeometry().getFirstCoordinate();
      let x = p[0];
      let y = p[1];
      // console.log(p)
      let x1, y1, x2, y2;
      r = r;
      if (!pos || pos === "u") {
        x1 = x - (o * 3.2 * r) / 10;
        y1 = y + (o * 2.4 * r) / 10;

        x2 = x - (o * 1 * r) / 10;
        y2 = y + (o * 1.4 * r) / 10;
      } else if (pos === "c") {
        x1 = x - (o * 3.2 * r) / 10;
        y1 = y + (o * 1 * r) / 10;

        x2 = x - (o * 1 * r) / 10;
        y2 = y - (o * 0 * r) / 10;
      } else if (pos === "d") {
        x1 = x - (o * 3.2 * r) / 10;
        y1 = y - (o * 0.4 * r) / 10;

        x2 = x - (o * 1 * r) / 10;
        y2 = y - (o * 1.4 * r) / 10;
      }

      return [
        [
          [x1, y1],
          [x2, y1],
          [x2, y2],
          [x1, y2],
          [x1, y1],
        ],
      ];
    },
    createTraceLayer() {
      // let that
      const that = this;
      let vectorLayer = new VectorLayer({
        source: new VectorSource({
          features: [],
        }),
        style: function (feature, resolution) {
          // 设置图标
          if (feature.values_.type == "route") {
            var geometry = feature.getGeometry();
            var linestyles = [
              // linestring
              new Style({
                stroke: new Stroke({
                  color: "#ff0000",
                  width: 2,
                }),
              }),
            ];

            geometry.forEachSegment(function (start, end) {
              var dx = end[0] - start[0];
              var dy = end[1] - start[1];
              var rotation = Math.atan2(dy, dx);
              // arrows
              linestyles.push(
                new Style({
                  geometry: new Point(end),
                  image: new Icon({
                    src: arrowImage,
                    scale: 0.5,
                    anchor: [1.35, 0.5],
                    rotateWithView: true,
                    rotation: -rotation,
                  }),
                })
              );
            });

            return linestyles;
          }
          var iconImage = positionImage;
          if (feature.values_.trans_type == "公交车") {
            iconImage = busImage;
          } else if (feature.values_.trans_type == "步行") {
            iconImage = walkingImage;
          } else if (feature.values_.trans_type == "出租车") {
            iconImage = taxiImage;
          } else if (feature.values_.trans_type == "骑行") {
            iconImage = ridingImage;
          } else if (feature.values_.trans_type == "地铁") {
            iconImage = subwayImage;
          }

          let styles = {
            trans: [
              new Style({
                image: new CircleStyle({
                  radius: 20,
                  fill: new Fill({
                    color: "rgba(244, 0, 0, 0.8)",
                  }),
                  stroke: new Stroke({
                    color: "rgba(244, 0, 0, 1)",
                  }),
                }),
              }),
              new Style({
                image: new Icon({
                  anchor: [0.5, 0.5],
                  scale: 0.18,
                  src: iconImage,
                  color: [255, 255, 255, 0.8],
                }),
              }),
              new Style({
                geometry: new Polygon(
                  that.createPolyon(feature, 200, resolution, "u")
                ),
                fill: new Fill({
                  color: "rgba(255,0, 0,0.7)",
                }),
                stroke: new Stroke({
                  color: "rgba(255,0, 0,1)",
                }),
                text: new TextStyle({
                  text: feature.values_.level1,
                  fill: new Fill({ color: "rgba(0,0,0,1)" }),
                  stroke: new Stroke({
                    color: "rgba(255,255,255,1)",
                    width: 2,
                  }),
                }),
              }),
              new Style({
                geometry: new Polygon(
                  that.createPolyon(feature, 200, resolution, "c")
                ),
                fill: new Fill({
                  color: "rgba(248,231,28,0.7)",
                }),
                stroke: new Stroke({
                  color: "rgba(248,231,28,1)",
                }),
                text: new TextStyle({
                  text: feature.values_.level2,
                  fill: new Fill({ color: "rgba(0,0,0,1)" }),
                  stroke: new Stroke({
                    color: "rgba(255,255,255,1)",
                    width: 2,
                  }),
                }),
              }),
              new Style({
                geometry: new Polygon(
                  that.createPolyon(feature, 200, resolution, "d")
                ),
                fill: new Fill({
                  color: "rgba(28,248,53,0.7)",
                }),
                stroke: new Stroke({
                  color: "rgba(28,248,53,1)",
                }),
                text: new TextStyle({
                  text: feature.values_.level3,
                  fill: new Fill({ color: "rgba(0,0,0,1)" }),
                  stroke: new Stroke({
                    color: "rgba(255,255,255,1)",
                    width: 2,
                  }),
                }),
              }),
            ],
            geoMarker: [
              new Style({
                image: new CircleStyle({
                  radius: 15,
                  fill: new Fill({
                    color: "rgba(28,121,248, 0.8)",
                  }),
                  stroke: new Stroke({
                    color: "rgba(28,121,248, 1)",
                  }),
                }),
                text: new TextStyle({
                  text: "" + feature.values_.index,
                  fill: new Fill({ color: "rgba(0,0,0,1)" }),
                  stroke: new Stroke({
                    color: "rgba(255,255,255,1)",
                    width: 2,
                  }),
                }),
              }),
              // new Style({
              //   image: new Icon({
              //     anchor: [0.5, 1],
              //     scale: 0.3,
              //     src: positionImage,
              //     color: [255, 255, 255, 0.8],
              //   }),
              // }),
              new Style({
                geometry: new Polygon(
                  that.createPolyon(feature, 200, resolution, "u")
                ),
                fill: new Fill({
                  color: "rgba(255,0, 0,0.7)",
                }),
                stroke: new Stroke({
                  color: "rgba(255,0, 0,1)",
                }),
                text: new TextStyle({
                  text: feature.values_.level1,
                  fontsize: "20",
                  fill: new Fill({ color: "rgba(255,255,255,1)" }),
                  stroke: new Stroke({
                    color: "rgba(0,0,0,1)",
                    width: 2,
                  }),
                }),
              }),
              new Style({
                geometry: new Polygon(
                  that.createPolyon(feature, 200, resolution, "c")
                ),
                fill: new Fill({
                  color: "rgba(248,231,28,0.7)",
                }),
                stroke: new Stroke({
                  color: "rgba(248,231,28,1)",
                }),
                text: new TextStyle({
                  text: feature.values_.level2,
                  fill: new Fill({ color: "rgba(0,0,0,1)" }),
                  stroke: new Stroke({
                    color: "rgba(255,255,255,1)",
                    width: 2,
                  }),
                }),
              }),
              new Style({
                geometry: new Polygon(
                  that.createPolyon(feature, 200, resolution, "d")
                ),
                fill: new Fill({
                  color: "rgba(28,248,53,0.7)",
                }),
                stroke: new Stroke({
                  color: "rgba(28,248,53,1)",
                }),
                text: new TextStyle({
                  text: feature.values_.level3,
                  fill: new Fill({ color: "rgba(0,0,0,1)" }),
                  stroke: new Stroke({
                    color: "rgba(255,255,255,1)",
                    width: 2,
                  }),
                }),
              }),
            ],
            buffer: new Style({
              fill: new Fill({
                color: "rgba(255,0, 0,0.4)",
              }),
            }),
          };
          // console.log(feature.get('type'))
          return styles[feature.get("type")];
        },
      });

      return vectorLayer;
    },
    createOneTrace(name, trace) {
      let points = [];
      // console.log(trace)
      trace.forEach((v, i) => {
        // console.log(v)
        let xy = fromLonLat([v.positions.lon, v.positions.lat]);
        let marker = new Feature({
          type: "geoMarker",
          geometry: new Point(xy),
          ...v,
          index: i,
          level1: "100人",
          level2: "100人",
          level3: "100人",
        });
        let bufferTT = new Feature({
          type: "buffer",
          geometry: new Circle(xy, 200),
        });
        // let textBoard = new Feature({
        //   type: "textBoard",
        //   geometry: new Polygon(this.createPolyon(xy, 200, 1)),
        //   text: "100人",
        // });
        // points.push(textBoard);

        points.push(marker);
        points.push(bufferTT);
      });
      let coors = trace.map((v) => {
        return fromLonLat([v.positions.lon, v.positions.lat]);
      });
      // console.log(coors)
      let lines = [];
      for (let i = 0; i < coors.length - 1; i++) {
        let line = new Feature({
          geometry: new LineString([coors[i], coors[i + 1]]),
          type: "route",
        });
        let center = [
          (coors[i][0] + coors[i + 1][0]) / 2,
          (coors[i][1] + coors[i + 1][1]) / 2,
        ];
        let trans = new Feature({
          type: "trans",
          geometry: new Point(center),
          trans_type: trace[i + 1].trans_type,
          level1: "100人",
          level2: "100人",
          level3: "100人",
        });
        lines.push(line);
        lines.push(trans);
      }
      let features = points.concat(lines);
      return features;
    },
    updateTrace() {
      context.traceLayer.getSource().clear();
      context.traceLayer.getSource().addFeatures(
        this.createOneTrace(
          "",
          this.trace.map((v) => v.trace)
        )
      );
    },
    startPicker() {
      context.pickerLayer.setVisible(true);
    },
  },
  mounted() {
    if (context.map) {
      console.log("!!!!!!!!!!!!");
    }
    this.init();
  },
};
</script>

<style>
#info {
  z-index: 1;
  opacity: 0;
  position: absolute;
  top: 0;
  left: 0;
  margin: 0;
  background: rgba(0, 60, 136, 0.7);
  color: white;
  border: 0;
  transition: opacity 100ms ease-in;
}

.el-collapse-item__header {
  text-align: center;
  border-radius: 25px;
  padding: 5px 30px;
  font-size: 150%;
}
</style>